<?php

defined('IN_MY_PHP') || die(0);

// for php v5.2~v5.3
if (!function_exists('session_status')) {
	define('PHP_SESSION_ACTIVE', 2);
	function session_status()
	{
		return session_id() === '' ? 1 : 2;
	}
}

/**
 * Session管理类，注意Sessoin固定攻击的使用.
 *
 * @author netmou <leiyanfo@sina.com>
 */
class Session
{

  public function start($expire = 0, $prefix = APPID)
  {
    if (session_status() !== PHP_SESSION_ACTIVE) {
      if (headers_sent($file, $line)) {
        trigger_error("Http-body has sent on {$line} in {$file}!", E_USER_ERROR);
    	}
	
			header('P3P: CP="CAO PSA OUR"');
			ini_set("session.cookie_httponly", 1);
			if($expire > 0){
				ini_set("session.gc_maxlifetime", $expire);
			}
			session_start();
			$timestamp = time();
			$access_times = $this->get('_ssn:access_times', 0, $prefix);
      if($access_times == 0){
				$this->set('_ssn:start_time', $timestamp, $prefix);
        $this->set('_ssn:access_times', 1, $prefix);
        $this->set('_ssn:last_access', $timestamp, $prefix);
      }else{
				$this->set('_ssn:access_times', $access_times + 1, $prefix);
				$this->set('_ssn:last_access', $timestamp, $prefix);
				$this->set('_ssn:ftk_vkey', '', $prefix);
			}
    }
  }

  public function set($key, $val, $prefix = APPID)
  {
    $this->start();
    $_SESSION[$prefix . $key] = $val;
  }

  public function delete($key, $prefix = APPID)
  {
    $this->start();
    unset($_SESSION[$prefix . $key]);
  }

  public function get($key, $def = null, $prefix = APPID)
  {
    $this->start();
    $val = $_SESSION[$prefix . $key];
    if ($val === null) {
      return $def;
    }

    return $val;
  }

  /** 获取会话的开始时间 */
  public function getStartTime($prefix = APPID)
  {
    return $this->get('_ssn:start_time', 0, $prefix);
	}
	
	/** 获取会话的上次访问时间 */
	public function getLastAccess($prefix = APPID){

		return $this->get('_ssn:last_access', 0, $prefix);
	}

	public function commit()
  {
    if (session_status() === PHP_SESSION_ACTIVE) {
      session_write_close();
    }
  }
  public function abort()
  {
    if (session_status() === PHP_SESSION_ACTIVE) {
      session_abort();
    }
	}

	public function isVerified($prefix = APPID){

		return $this->get('_ssn:ftk_vkey', '', $prefix) != '';
	}
	
  /** 验证表单提交的token是否有效 */
  public function verifyToken($ftk_key, $token, $prefix = APPID)
  {
		$data = $this->get('_ssn:ftk_data', array(), $prefix);
		if($data[$ftk_key] != '' && $token == $data[$ftk_key]){
			unset($data[$ftk_key]);
			$this->set('_ssn:ftk_vkey', $ftk_key, $prefix);
			$this->set('_ssn:ftk_data', $data, $prefix);
			return true;
		}else{
			$this->set('_ssn:ftk_vkey', '', $prefix);
			return false;
		}
	}

  /** 在POST表单中含有 token 关键字的令牌信息，会在入口处自动验证 */
  public function formTokenInput($prefix = APPID){
		$data = $this->get('_ssn:ftk_data', array(), $prefix);
		$ftkey = 'ftk_';
		for($i = 0; $i < 8; $i++){
			$ftkey .= chr(rand(48, 57));
		}
		$token = (count($data)+1).'_';
		for($i = 0; $i < 8; $i++){
			$token .= chr(rand(97, 122));
		}

		$data[$ftkey] = $token;
		$this->set('_ssn:ftk_data', $data, $prefix);
		return "<input type=\"hidden\" name=\"{$ftkey}\" value=\"{$token}\">";
	}

  /** 清空当前应用的会话 */
  public function appClear($prefix = APPID)
  {
    $this->start();
		if($len = strlen($prefix)){
			$keySet = array_keys($_SESSION);
			foreach ($keySet as &$key) {
				if($prefix === substr($key, 0, $len)) {
					unset($_SESSION[$key]);
				}
			}
		}else{
			$_SESSION = array();
		}
		
	}
}